import akshare as ak
import pandas as pd

# 设置 Pandas 显示选项，以便完整打印 DataFrame
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)


# --- 股票实时行情查询函数 ---
def get_multiple_stocks_data(stock_codes):
    """
    使用 akshare 一次性获取多只A股的实时行情数据。
    """
    if not isinstance(stock_codes, list) or not stock_codes:
        print("输入参数应为非空的股票代码列表。")
        return None

    try:
        stock_zh_a_spot_df = ak.stock_zh_a_spot_em()
        result_df = stock_zh_a_spot_df[stock_zh_a_spot_df['代码'].isin(stock_codes)]
        return result_df
    except Exception as e:
        print(f"获取股票实时数据时发生错误：{e}")
        return None


# --- 基金涨幅计算主函数 ---
def calculate_fund_change_rate(fund_code, reporting_year):
    """
    根据基金持仓股票的实时涨跌，计算基金的估算涨幅。

    Args:
        fund_code (str): 基金代码，如 '005827'。
        reporting_year (str): 财报年度，如 '2025'。

    Returns:
        float: 基金的估算涨幅（以百分比表示）。
    """
    print(f"--- 正在获取基金 {fund_code} {reporting_year} 年度的持仓信息 ---")
    try:
        # 1. 获取基金持仓信息
        # 该接口返回指定年度的所有季度持仓数据
        fund_portfolio_all_quarters = ak.fund_portfolio_hold_em(symbol=fund_code, date=reporting_year)

        print(fund_portfolio_all_quarters)


        if fund_portfolio_all_quarters.empty:
            print("未能获取到基金的持仓股票信息。")
            return None

        # 提取最新一个季度的持仓数据
        # 接口返回的数据已经按日期降序排列，所以最新数据在最前面
        latest_quarter_data = fund_portfolio_all_quarters.iloc[0]['股票代码']

        print(latest_quarter_data)

        # 提取股票代码和持仓比例
        stock_data = latest_quarter_data[['股票代码', '持仓比例']]
        print("stock data:", stock_data)
        stock_codes_list = stock_data['股票代码'].tolist()

        print(f"\n--- 获取到基金最新持仓股票 {len(stock_codes_list)} 只 ---")

        # 2. 获取所有持仓股票的实时行情
        print(f"\n--- 正在查询持仓股票的实时行情 ---")
        realtime_stock_data = get_multiple_stocks_data(stock_codes_list)

        if realtime_stock_data is None or realtime_stock_data.empty:
            print("未能获取到持仓股票的实时行情，无法计算涨幅。")
            return None

        # 3. 合并数据并计算涨幅
        # 将基金持仓数据与股票实时行情数据合并
        merged_data = pd.merge(stock_data, realtime_stock_data,
                               left_on='股票代码', right_on='代码', how='inner')

        # 确保关键列存在且不是空值
        merged_data.dropna(subset=['持仓比例', '涨跌幅'], inplace=True)

        # 计算每只股票对基金涨幅的贡献
        # 涨跌贡献 = 持仓比例 * 股票涨跌幅（接口返回的涨跌幅已经是百分比）
        merged_data['涨幅贡献'] = merged_data['持仓比例'] * merged_data['涨跌幅']

        # 计算基金的总估算涨幅
        estimated_fund_change_rate = merged_data['涨幅贡献'].sum()

        print("\n--- 基金持仓股票实时数据 ---")
        print(merged_data[['股票代码', '股票名称', '持仓比例', '涨跌幅', '涨幅贡献']])

        print("\n--- 基金实时涨幅估算 ---")
        print(f"基金 {fund_code} 的实时估算涨幅为: {estimated_fund_change_rate:.2f}%")

        return estimated_fund_change_rate

    except Exception as e:
        print(f"计算基金涨幅时发生错误：{e}")
        return None


# --- 调用示例 ---
# 基金代码：易方达蓝筹精选混合A
fund_code_to_query = "018956"
# 最新财报年度
reporting_year = "2025"

calculate_fund_change_rate(fund_code_to_query, reporting_year)